package com.edu.elasticsearch;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.edu.common.model.PageQuery;
import com.edu.common.utils.ResourceUtil;


public class ElasticSearchHandler {
	
	private String indexName;
	private String type;
	
	private static Logger logger = LoggerFactory.getLogger(ElasticSearchHandler.class);

	static public TransportClient client = null;

	public static TransportClient getClient() {
		try {
			if (client == null) {
				Settings settings = Settings.settingsBuilder().put("cluster.name", ResourceUtil.getESClusterName()).put("client.transport.sniff", true).build();
				client = TransportClient.builder().settings(settings).build();
				//ip支持集群设置，按逗号分割
				String ips = ResourceUtil.getESServerIp();
				if(StringUtils.isNotBlank(ips)){
					if(ips.contains(",")){
						String[] ipArray = ips.split(",");
						for(String ip:ipArray){
							client.addTransportAddress(newAddress(ip, Integer.parseInt(ResourceUtil.getESServerPort())));
						}
					}else{
						client.addTransportAddress(newAddress(ips, Integer.parseInt(ResourceUtil.getESServerPort())));
					}
				}
			}
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return client;
	}

	private static InetSocketTransportAddress newAddress(String host, int port) throws UnknownHostException {
		return new InetSocketTransportAddress(InetAddress.getByName(host), port);
	}
	
	public ElasticSearchHandler() {
		getClient();
	}

	public ElasticSearchHandler(String indexName,String type) {
		this.indexName = indexName;
		this.type = type;
		getClient();
	}

	/**
	 * 执行搜索
	 * @param queryBuilder
	 * @param queryBean ESQueryBean
	 * @return
	 */
	public PageQuery<Object> searcherByPagenation(QueryBuilder queryBuilder, ESQueryBean queryBean) {
		List<Object> list = new ArrayList<Object>();
		SearchResponse searchResponse = client.prepareSearch(getIndexName())
				.setTypes(getType())
				.setQuery(queryBuilder)
				.addSort(queryBean.getOrderField(), queryBean.getSortOrder())
				.setFrom(queryBean.getPage()).setSize(queryBean.getSize())
				.execute().actionGet();
		SearchHits hits = searchResponse.getHits();
		logger.debug("查询到记录数=" + hits.getTotalHits());
		SearchHit[] searchHists = hits.getHits();
		if (searchHists.length > 0) {
			for (SearchHit hit : searchHists) {
				list.add(hit.getSource());
			}
		}
		PageQuery<Object> pageQuery = new PageQuery<Object>(queryBean.getSize(), queryBean.getPage());
		pageQuery.setTotal((int)hits.getTotalHits());
		pageQuery.setRows(list);
		return pageQuery;
	}
	
	/**
	 * 执行搜索
	 * @param queryBuilder
	 * @param queryBean ESQueryBean
	 * @return
	 */
	public List<Object> searcher(QueryBuilder queryBuilder, ESQueryBean queryBean) {
		List<Object> list = new ArrayList<Object>();
		SearchResponse searchResponse = client.prepareSearch(getIndexName())
				.setTypes(getType())
				.setQuery(queryBuilder)
				.addSort(queryBean.getOrderField(), queryBean.getSortOrder())
				.execute().actionGet();
		SearchHits hits = searchResponse.getHits();
		SearchHit[] searchHists = hits.getHits();
		if (searchHists.length > 0) {
			for (SearchHit hit : searchHists) {
				list.add(hit.getSource());
			}
		}
		return list;
		
	}
	
	/**
	 * 构建查询条件
	* @param @param obj
	* @param @return   
	* @return QueryBuilder  
	* @throws
	 */
	public QueryBuilder initParams(Map<String,Object> params){
		BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
		if(null!=params){
			for(Entry<String, Object> entry:params.entrySet()){
				if(!StringUtils.isEmpty(entry.getKey()) && entry.getValue()!=null){
					if(!(entry.getValue() instanceof Date)){
						//相当于 ADN
						queryBuilder.must(QueryBuilders.matchQuery(entry.getKey(),entry.getValue()));
					}else if(entry.getValue() instanceof String[]){
						//相当于  IN
						queryBuilder.must(QueryBuilders.termsQuery(entry.getKey(), entry.getValue()));
					}
				}
			}
			filterDate(params,queryBuilder);
		}
		return queryBuilder;
	}
	
	public void filterDate(Map<String,Object> params,BoolQueryBuilder queryBuilder){
		//注册时间
		if(params.containsKey("startRegistTime") && params.containsKey("endRegistTime")){
			Date fromDate = (Date) params.get("startRegistTime");
			Date toDate = (Date) params.get("endRegistTime");
			queryBuilder.filter(QueryBuilders.rangeQuery("addTime").from(fromDate).to(toDate));
		}
		//上一次登录时间
		if(params.containsKey("startPreLoginTime") && params.containsKey("endPreLoginTime")){
			Date fromDate = (Date) params.get("startPreLoginTime");
			Date toDate = (Date) params.get("endPreLoginTime");
			queryBuilder.filter(QueryBuilders.rangeQuery("modifTime").from(fromDate).to(toDate));
		}
	}
	
	public void delete(String id) {
		DeleteResponse deleteresponse = client.prepareDelete(getIndexName(), getType(), id).execute().actionGet();
		logger.debug("删除记录=" + deleteresponse.getId());
	}  

	public String getIndexName() {
		return indexName;
	}

	public void setIndexName(String pIndexName) {
		indexName = pIndexName;
	}

	public String getType() {
		return type;
	}

	public void setType(String pType) {
		type = pType;
	}
	
}